﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Xml;

namespace EnCor.Config
{
    public class ModuleConfigCollection : ConfigurationElementCollection
    {
        public ModuleConfigCollection()
        {
            this.AddElementName = "module";
        }


        protected override ConfigurationElement CreateNewElement()
        {
            return new ModuleConfig();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((ModuleConfig)element).Name;

        }

        protected override bool OnDeserializeUnrecognizedElement(string elementName, System.Xml.XmlReader reader)
        {
            if (Constants.Config_Module == elementName)
            {
                ModuleConfig config = Deserialize(reader);

                //Type configType = RetrieveConfigurationElementType(reader);
                //if (configType == null)
                //{
                //    throw new EnCorException(string.Format("Cannot find the type {0}", configType));
                //}

                //if (configType == null)
                //{
                //    throw new EnCorException(string.Format("Cannot find the type {0}", configType));
                //}


                //if (!(typeof(ModuleConfig).IsAssignableFrom(configType)))
                //{
                //    throw new EnCorException("Invalid config type");
                //}

                //ModuleConfig specialconfig = (ModuleConfig)Activator.CreateInstance(configType);
                //specialconfig.DeserializeElement(reader);


                BaseAdd(config);

                return true;

            }
            return base.OnDeserializeUnrecognizedElement(elementName, reader);
        }

        private ModuleConfig Deserialize(XmlReader reader)
        {
            Type configDataType = RetrieveConfigurationElementType(reader);
            if (configDataType == null)
            {
                configDataType = typeof(ModuleConfig);
            }

            ModuleConfig specialconfig = (ModuleConfig)Activator.CreateInstance(configDataType);
            specialconfig.DeserializeElement(reader);
            return specialconfig;
        }

        private Type RetrieveConfigurationElementType(XmlReader reader)
        {
            Type configurationElementType = null;


            if (reader.AttributeCount > 0)
            {
                // expect the first attribute to be the name
                for (bool go = reader.MoveToFirstAttribute(); go; go = reader.MoveToNextAttribute())
                {
                    if (reader.Name == Constants.Config_DataType)
                    {
                        configurationElementType = Type.GetType(reader.Value);
                        if (configurationElementType == null)
                        {
                            throw new ConfigurationErrorsException(
                                string.Format( "Invalid config type : {0}" ,reader.ReadOuterXml()));
                        }
                        break;
                    }
                }
                // cover the traces
                reader.MoveToElement();
            }

            return configurationElementType;
        }


    }
}
